home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / slip / cslip-2.6 / tip / libacu / telebit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-30  |  7.4 KB  |  376 lines

  1. /*
  2.  * Copyright (c) 1983 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that: (1) source distributions retain this entire copyright
  7.  * notice and comment, and (2) distributions including binaries display
  8.  * the following acknowledgement:  ``This product includes software
  9.  * developed by the University of California, Berkeley and its contributors''
  10.  * in the documentation or other materials provided with the distribution
  11.  * and in all advertising materials mentioning features or use of this
  12.  * software. Neither the name of the University nor the names of its
  13.  * contributors may be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. static char rcsid[] =
  22.     "@(#) $Header: telebit.c,v 1.18 92/07/30 14:29:32 leres Exp $ (LBL)";
  23. #endif
  24.  
  25. #include "tip.h"
  26. #include <sys/time.h>
  27.  
  28. static char NAME[] = "telebit";
  29.  
  30. /* result codes */ ;
  31. static char RRING[] = "\r\nRRING\r\n";
  32. static char CONNECT[] = "\r\nCONNECT";    /* generic prefix */
  33.  
  34. #define    CMD_DELAY    5    /* number of seconds to wait for response
  35.                  * while in command mode */
  36. #define DIAL_DELAY    120    /* number of seconds to wait for response
  37.                  * after sending dial string */
  38. #define WRITE_DELAY    100    /* ms between each character written to modem */
  39. #define    MAXSTR    256
  40.  
  41. void
  42. tb_disconnect()
  43. {
  44.  
  45.     (void) close(FD);
  46. }
  47.  
  48. void
  49. tb_abort()
  50. {
  51.  
  52.     tb_disconnect();
  53. }
  54.  
  55. static void
  56. tberrputc(c)
  57.     char c;
  58. {
  59.  
  60.     if (c & ~0177) {
  61.         putc('M', stderr);
  62.         putc('-', stderr);
  63.         c &= 0177;
  64.     }
  65.     switch (c) {
  66.  
  67.     case '\r':
  68.         putc('\\', stderr);
  69.         putc('r', stderr);
  70.         break;
  71.  
  72.     case '\n':
  73.         putc('\\', stderr);
  74.         putc('n', stderr);
  75.         break;
  76.  
  77.     case '\t':
  78.         putc('\\', stderr);
  79.         putc('t', stderr);
  80.         break;
  81.  
  82.     default:
  83.         if (c < 0x20) {
  84.             putc('^', stderr);
  85.             putc(c + 0x40, stderr);
  86.         } else
  87.             putc(c, stderr);
  88.     }
  89.     (void) fflush(stderr);
  90. }
  91.  
  92. static void
  93. tberrputs(s)
  94.     register char *s;
  95. {
  96.  
  97.     while (*s)
  98.         tberrputc(*s++);
  99. }
  100.  
  101. /* Trim leading and trailing white space */
  102. static char *
  103. tbpretty(s)
  104.     register char *s;
  105. {
  106.     register char *cp;
  107.  
  108.     cp = s;
  109.     cp += strlen(s) - 1;
  110.     while (cp > s && isspace(*cp & 0177))
  111.         *cp-- = '\0';
  112.     cp = s;
  113.     while (isspace(*cp & 0177))
  114.         cp++;
  115.     return(cp);
  116. }
  117.  
  118. static void
  119. tbputc(c)
  120.     char c;
  121. {
  122.     struct timeval t;
  123.  
  124.     if (write(FD, &c, 1) != 1) {
  125.         perror("tip: tbputc: write error");
  126.         return;
  127.     }
  128.     if (debug)
  129.         tberrputc(c);
  130.     t.tv_sec = 0;
  131.     t.tv_usec = WRITE_DELAY * 1000000;
  132.     (void) select(32, 0, 0, 0, &t);
  133. }
  134.  
  135. static void
  136. tbwrite(cp)
  137.     register char *cp;
  138. {
  139.  
  140.     if (debug) {
  141.         (void) fprintf(stderr, "-> \"");
  142.         (void) fflush(stderr);
  143.     }
  144.     while (*cp != '\0')
  145.         tbputc(*cp++);
  146.     if (debug) {
  147.         (void) fprintf(stderr, "\"\n");
  148.         (void) fflush(stderr);
  149.     }
  150. }
  151.  
  152. static char
  153. tbgetc(timeout)
  154.     unsigned int timeout;
  155. {
  156.     int n;
  157.     char c;
  158.     struct timeval t;
  159.     int readfds;
  160.  
  161.     t.tv_sec = timeout;
  162.     t.tv_usec = 0;
  163.     readfds = 1 << FD;
  164.     if ((n = select(FD+1, &readfds, 0, 0, &t)) <= 0) {
  165.         if (n < 0)
  166.             perror("tbgetc: select");
  167.         return (0);
  168.     }
  169.     if ((n = read(FD, &c, 1)) <= 0) {
  170.         perror("tbgetc: read");
  171.         return (0);
  172.     }
  173.     if (debug)
  174.         tberrputc(c);
  175.     return (c);
  176. }
  177.  
  178. /*
  179.  * Read a line from the telebit. We assume a line will begin
  180.  * with a carriage return/line feed and end with line feed.
  181.  */
  182. static int
  183. tbread(buf, timeout, max)
  184.     char *buf;
  185.     unsigned int timeout, max;
  186. {
  187.     char *cp = buf;
  188.     char c;
  189.     int ret = 1;
  190.  
  191.     if (debug) {
  192.         (void) fprintf(stderr, "<- \"");
  193.         (void) fflush(stderr);
  194.     }
  195.     *buf = '\0';
  196.  
  197.     /* get the initial \r \n */
  198.     if ((*cp++ = tbgetc(timeout)) == 0) {
  199.         ret = 0;
  200.         goto bail;
  201.     }
  202.     if ((*cp++ = tbgetc(timeout)) == 0) {
  203.         ret = 0;
  204.         goto bail;
  205.     }
  206.  
  207.     /* grab everything up to the next \n */
  208.     while (cp < &buf[max - 2] && (*cp++ = c = tbgetc(timeout)) != '\n')
  209.         if (c == 0) {
  210.             ret = 0;
  211.             goto bail;
  212.         }
  213.     *cp = '\0';
  214.  
  215. bail:
  216.     if (debug) {
  217.         (void) fprintf(stderr, "\"\n");
  218.         (void) fflush(stderr);
  219.     }
  220.     return(ret);
  221. }
  222.  
  223. static int
  224. tbset(tosend, buf, num, errmsg)
  225.     char *tosend, *buf, *num, *errmsg;
  226. {
  227.     tbwrite(tosend);
  228.     tbread(buf, CMD_DELAY, MAXSTR);
  229.     if (strcmp(tbpretty(buf), "OK") != 0) {
  230.         (void) printf(" %s modem %s\n", NAME, errmsg);
  231.         (void) fflush(stdout);
  232. #ifdef ACULOG
  233.         logent(value(HOST), num, NAME, errmsg);
  234. #endif
  235.         return (1);
  236.     }
  237.     return (0);
  238. }
  239.  
  240. tb_dialer(num, acu)
  241.     register char *num;
  242.     char *acu;
  243. {
  244.     int i;
  245.     char buf[MAXSTR];
  246.     register char *cp;
  247.     int verbose = boolean(value(VERBOSE));
  248.     char c;
  249.  
  250.     /*
  251.      * Make sure that we get a HUP if anything goes wrong then turn
  252.      * off echo (in case it's on) to make our response parsing easier.
  253.      */
  254.     if (verbose) {
  255.         (void) printf("diddling dialer... ");
  256.         if (debug)
  257.             putchar('\n');
  258.         (void) fflush(stdout);
  259.     }
  260.     if (ioctl(FD, TIOCHPCL, 0) < 0)
  261.         perror("tip: TIOCHPCL ioctl");
  262.     tbwrite("\rATE0\r");
  263.     if (debug) {
  264.         (void) fprintf(stderr, "<- \"");
  265.         (void) fflush(stderr);
  266.     }
  267.     while ((c = tbgetc(CMD_DELAY)) != 'O')
  268.         if (c == 0) {
  269.             (void) fprintf(stderr, "\"\ntelebit not responding\n");
  270.             (void) fflush(stderr);
  271.             return (0);
  272.         }
  273.     while ((c = tbgetc(CMD_DELAY)) != '\n')
  274.         if (c == 0) {
  275.             (void) fprintf(stderr,
  276.                 "\"\ntelebit not responding (2)\n");
  277.             (void) fflush(stderr);
  278.             return (0);
  279.         }
  280.     if (debug) {
  281.         (void) fprintf(stderr, "\"\n");
  282.         (void) fflush(stderr);
  283.     }
  284.  
  285.     /* See if we can figure out what we're dealing with */
  286.     i = -1;
  287.     tbwrite("\rATI\r");
  288.     if (!tbread(buf, CMD_DELAY, sizeof(buf)) ||
  289.         (cp = tbpretty(buf)) == 0 ||
  290.         *cp == '\0' ||
  291.         (i = atoi(cp)) == 0 ||
  292.         !tbread(buf, CMD_DELAY, sizeof(buf)) ||
  293.         strcmp(tbpretty(buf), "OK") != 0) {
  294.         (void) fprintf(stderr, "Can't determine telebit model %d\n", i);
  295.         (void) fflush(stderr);
  296.         return(0);
  297.     }
  298.     switch (i) {
  299.  
  300.     case 965:        /* T1600, T3000, WorldBlazer */
  301.         cp = "\rATQ0 X1\r";
  302.         break;
  303.  
  304.     case 968:        /* T1000 */
  305.     case 971:        /* T2500 */
  306.     default:
  307.         cp = "\rAT~Q0 X3 W1\r";
  308.         break;
  309.     }
  310.     if (debug > 1)
  311.         (void) printf("[modem type %d]\n", i);
  312.  
  313.     /* Setup a few things, bail if any fail */
  314.     if (tbset(cp, buf, num, "telebit result codes not set"))
  315.         return (0);
  316.  
  317.     /* if the "phone number" doesn't start with a digit, assume it's
  318.      * a command string to go to the telebit */
  319.     if (verbose) {
  320.         (void) printf("dialing... ");
  321.         if (debug)
  322.             putchar('\n');
  323.         (void) fflush(stdout);
  324.     }
  325.     if (isdigit(*num))
  326.         (void) sprintf(buf, "ATD%s\r", num);
  327.     else
  328.         (void) sprintf(buf, "AT%s\r", num);
  329.     tbwrite(buf);
  330.  
  331.     while (1) {
  332.         if (tbread(buf, DIAL_DELAY, sizeof(buf)) == 0) {
  333.             (void) strcpy(buf, "timeout on dial");
  334. #ifdef ACULOG
  335.             logent(value(HOST), num, NAME, buf);
  336. #endif
  337.             return (0);
  338.         }
  339.         if (strncmp(buf, RRING, strlen(RRING)))
  340.             break;
  341.         if (verbose) {
  342.             (void) printf("ringing...");
  343.             if (debug)
  344.                 putchar('\n');
  345.             (void) fflush(stdout);
  346.         }
  347.     }
  348.  
  349.     if (strncmp(buf, CONNECT, strlen(CONNECT)) != 0) {
  350.         char buf2[MAXSTR];
  351.  
  352.         (void) sprintf(buf2, "dial failed (%s)", tbpretty(buf));
  353.         (void) printf("%s", buf2);
  354.         (void) fflush(stdout);
  355. #ifdef ACULOG
  356.         logent(value(HOST), num, NAME, buf2);
  357. #endif
  358.         return (0);
  359.     }
  360.     /*
  361.      * We assume the modem has lock speed set so we don't care
  362.      * what the connect speed was.
  363.      */
  364.     ttysetup(speed(BR));
  365.     if (verbose) {
  366.         (void) printf("(%s)", tbpretty(buf));
  367.         if (debug)
  368.             putchar('\n');
  369.         (void) fflush(stdout);
  370.     }
  371.     i = 2;
  372.     if (ioctl(FD, TIOCFLUSH, &i) < 0)
  373.         perror("tip: TIOCFLUSH ioctl");
  374.     return (1);
  375. }
  376.